Skip to content

Conversation

humanzz
Copy link
Contributor

@humanzz humanzz commented Sep 29, 2025

Summary

Changes

Please provide a summary of what's being changed

Please add the issue number below, if no issue is present the PR might get blocked and not be reviewed

  • introduce Metrics.flushMetrics as a more powerful version of flushSingleMetrics to allow
    • using defaults by inheriting state e.g. namespace, dimensions and properties
    • emitting multiple metrics in one metrics context
  • update EmfMetricsLogger.addMetadata to use emf's putProperty
  • refactor flushSingleMetrics and captureColdStartMetric to use flushMetrics
  • consolidate request id and trace id setting into a newly introduced internal MetricsUtils

Issue number: #2153


By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

Disclaimer: We value your time and bandwidth. As such, any pull requests created on non-triaged issues might not be successful.

- introduce `Metrics.flushMetrics` as a more powerful version of `flushSingleMetrics` to allow
  - using defaults by inheriting state e.g. namespace, dimensions and metadata
  - emitting multiple metrics in one metrics context
- refactor `flushSingleMetrics` to use `flushMetrics`
- move namespace/service setting from `MetricsFactory` to `EmfMetricsLogger`
- introduce `Metrics.flushMetrics` as a more powerful version of `flushSingleMetrics` to allow
  - using defaults by inheriting state e.g. namespace, dimensions and metadata
  - emitting multiple metrics in one metrics context
- refactor `flushSingleMetrics` to use `flushMetrics`
- move namespace/service setting from `MetricsFactory` to `EmfMetricsLogger`
Copy link
Contributor

@phipag phipag left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @humanzz for sending this PR. Overall, it looks good and I left some comments that we need to address before moving forward.

Primarily, can you go back to the issue #2153 and let us know your use-case? We still need to decide whether we want to move forward with inheriting the default configuration of the metrics logger for flushMetrics and flushSingleMetric.

@humanzz
Copy link
Contributor Author

humanzz commented Sep 30, 2025

I've addressed the metricsContext comments in 4730be4, and will leave details about the use case on the feature request.

Copy link
Contributor

@phipag phipag left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the quick turnaround @humanzz. Just one more thing that I discovered.

@phipag
Copy link
Contributor

phipag commented Sep 30, 2025

@phipag another observation/inconsistency is the usage of putProperty vs. putMetadata. See

* https://github.com/aws-powertools/powertools-lambda-java/blob/main/powertools-metrics/src/main/java/software/amazon/lambda/powertools/metrics/internal/EmfMetricsLogger.java#L212

* https://github.com/aws-powertools/powertools-lambda-java/blob/main/powertools-metrics/src/main/java/software/amazon/lambda/powertools/metrics/internal/LambdaMetricsAspect.java#L95

Good catch! It seems that a "property" is simply a key added to the log line while "metadata" becomes part of the _aws object. These are logs from the official example:

Cold start metric (putProperty)

{
    "_aws": {
        "Timestamp": 1751977621635,
        "CloudWatchMetrics": [
            {
                "Namespace": "ServerlessAirline",
                "Metrics": [
                    {
                        "Name": "ColdStart",
                        "Unit": "Count"
                    }
                ],
                "Dimensions": [
                    [
                        "Service",
                        "FunctionName"
                    ]
                ]
            }
        ]
    },
    "function_request_id": "b8628984-b745-44bb-8025-247c2da76da1",
    "xray_trace_id": "1-686d0e92-396456d519ba8c28174120a4",
    "ColdStart": 1,
    "Service": "payment",
}

Regular metric (putMetadata)

{
    "_aws": {
        "Timestamp": 1751977946689,
        "CloudWatchMetrics": [
            {
                "Namespace": "ServerlessAirline",
                "Metrics": [
                    {
                        "Name": "CustomMetric1",
                        "Unit": "Count"
                    },
                    {
                        "Name": "CustomMetric3",
                        "Unit": "Count",
                        "StorageResolution": 1
                    }
                ],
                "Dimensions": [
                    [
                        "Service"
                    ]
                ]
            }
        ],
        "function_request_id": "feccb848-47a9-4b32-a16b-73d45d7ad308",
        "xray_trace_id": "1-686d0fdb-651f4fc05b57221e726890c0"
    },
    "CustomMetric1": 1,
    "Service": "payment",
    "CustomMetric3": 1
}

I need to find out the semantic difference – those nuances don't exist in the other runtimes. None of it is searchable in cloudwatch metrics. Besides the location in the json output I don't see any difference.


Update:

It appears that putMetadata will add key-value pairs to the _aws (metadata) object. Adding things there will not have an effect. Only Timestamp which is the officially documented metadata key in addition to CloudWatchMetrics (https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Embedded_Metric_Format_Specification.html#CloudWatch_Embedded_Metric_Format_Specification_structure_metadata%22%3ECloudWatch%20%20%20%20%20*%20%20%20%20%20Metadata). We shouldn't use this since it is nowhere documented and favor putProperty: https://github.com/awslabs/aws-embedded-metrics-java

We should update the addMetadata method to call putProperty on the EMF logger since this is the officially documented method (putMetadata is not documented). This is consistent with e.g. Python (see https://docs.powertools.aws.dev/lambda/python/latest/core/metrics/#add_metadata_outputjson)

Copy link
Contributor

@phipag phipag left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @humanzz for your continued engagement. Everything looks good so far besides these minor comments. 🚀

The final step after this will be to update the documentation with the new flushMetrics method including code examples showing developers how to use it. Let me know if you would like to do this – otherwise I am happy to commit the documentation into this PR.

The docs file uses mkdocs and is located here docs/core/metrics.md.

Copy link
Contributor

@phipag phipag left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome! Final small comment (you can commit directly from GitHub UI I think).

Co-authored-by: Philipp Page <philipp.page@yahoo.de>
Copy link

sonarqubecloud bot commented Oct 1, 2025

Copy link
Contributor

@phipag phipag left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you @humanzz for raising the bar. Your attention to detail significantly improved this module!

These changes look good to me. Let me align with the other runtimes and make a merge decision! 🚀

@phipag phipag self-assigned this Oct 1, 2025
@phipag phipag moved this to Pending review in Powertools for AWS Lambda (Java) Oct 1, 2025
@phipag
Copy link
Contributor

phipag commented Oct 2, 2025

Aligned. I am merging this PR. Congrats @humanzz on this awesome contribution! 🎉

@phipag phipag merged commit fe5aef6 into aws-powertools:main Oct 2, 2025
11 checks passed
@github-project-automation github-project-automation bot moved this from Pending review to Coming soon in Powertools for AWS Lambda (Java) Oct 2, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Coming soon
Development

Successfully merging this pull request may close these issues.

Feature request: Reuse namespace in Metrics.flushSingleMetric and other limitations
2 participants